﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 **/

using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Peter.Ftp.Data;

namespace Peter.Ftp.Tests.Data
{
   /// <summary>
   /// Test cases for the FtpConnectionData class.
   /// </summary>
   [TestClass]
   public class FtpConnectionDataTests
   {
      private bool m_HasChanged;

      /// <summary>
      /// Tests some default properties of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestDefaults ()
      {
         var data = new FtpConnectionData ();
         // These should have defaults...
         Assert.AreEqual (10, data.Timeout, "No default timeout specified.");
         Assert.AreEqual (21, data.Port);
         Assert.AreEqual ("/", data.WorkingPath);
         Assert.IsFalse (data.AskForPassword);
         // These should be empty by default...
         Assert.IsTrue (string.IsNullOrEmpty (data.Name));
         Assert.IsTrue (string.IsNullOrEmpty (data.UserName));
         Assert.IsTrue (string.IsNullOrEmpty (data.Server));
         Assert.IsTrue (string.IsNullOrEmpty (data.Password));
         Assert.IsTrue (string.IsNullOrEmpty (data.SecurePassword));
      }

      /// <summary>
      /// Tests the Name property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestNameProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         data.Name = "TestName";
         Assert.AreEqual ("TestName", data.Name, "Name property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "Name property did not fire a property change notification.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the UserName property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestUserNameProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         data.UserName = "TestUserName";
         Assert.AreEqual ("TestUserName", data.UserName, "UserName property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "UserName property did not fire a property change notification.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the Server property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestServerProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         data.Server = "TestServer";
         Assert.AreEqual ("TestServer", data.Server, "Server property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "Server property did not fire a property change notification.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the WorkingPath property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestWorkingPathProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         data.WorkingPath = "TestWorkingPath";
         Assert.AreEqual ("TestWorkingPath", data.WorkingPath, "WorkingPath property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "WorkingPath property did not fire a property change notification.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the Port property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestPortProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         data.Port = 22;
         Assert.AreEqual (22, data.Port, "Port property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "Port property did not fire a property change notification.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the Timeout property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestTimeoutProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         data.Timeout = 20;
         Assert.AreEqual (20, data.Timeout, "Timeout property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "Timeout property did not fire a property change notification.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the AskForPassword property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestAskForPasswordProperty ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData { Password = "Password" };
         data.PropertyChanged += this.OnPropertyChanged;
         Assert.IsFalse (string.IsNullOrEmpty (data.Password), "Password should have a value for the start of the test.");

         // If the value has not changed, it should not raise a change notification...
         data.AskForPassword = data.AskForPassword;
         Assert.IsFalse (this.m_HasChanged);

         data.AskForPassword = true;
         Assert.AreEqual (true, data.AskForPassword, "AskForPassword property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "AskForPassword property did not fire a property change notification.");
         Assert.IsTrue (string.IsNullOrEmpty (data.Password), "The password should be cleared when changing AskForPassword to true.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Tests the Password and SecurePassword property of FtpConnectionData.
      /// </summary>
      [TestMethod]
      public void TestPasswordProperties ()
      {
         this.m_HasChanged = false;
         var data = new FtpConnectionData ();
         data.PropertyChanged += this.OnPropertyChanged;

         // If the value has not changed, it should not raise a change notification...
         data.Password = data.Password;
         Assert.IsFalse (this.m_HasChanged);
         data.SecurePassword = data.SecurePassword;
         Assert.IsFalse (this.m_HasChanged);

         data.Password = "Password";
         Assert.AreEqual ("Password", data.Password, "Password property did not change to the expected value.");
         Assert.IsTrue (this.m_HasChanged, "Password property did not fire a property change notification.");
         Assert.IsFalse (string.IsNullOrEmpty (data.SecurePassword), "The SecurePassword should be set when setting the Password.");
         Assert.AreEqual (data.Password, Crypto.DecryptStringAes (data.SecurePassword, "IFOODOAKANFRJDKV"), "The SecurePassword does not match the Password.");

         data.PropertyChanged -= this.OnPropertyChanged;
      }

      /// <summary>
      /// Occurs when a property change notification has been detected.
      /// </summary>
      /// <param name="sender">FtpConnectionData object.</param>
      /// <param name="e">PropertyChangedEventArgs</param>
      private void OnPropertyChanged (object sender, PropertyChangedEventArgs e)
      {
         this.m_HasChanged = true;
      }
   }
}
